Arranging Components Using Row, Column, and Box in Jetpack Compose
Course: Android App Development
Topic: Arranging Components Using Row, Column, and Box
Course Link: Android App Development Course – JustAcademy
Demo Link: Register for a Course Demo
Official Documentation: Compose Layout Basics – Android Developers
1. Introduction to Layouts in Jetpack Compose
Jetpack Compose is a modern Android UI toolkit that allows developers to create native user interfaces using Kotlin. Instead of defining layouts primarily through XML files, Compose uses composable functions to describe how interface elements should appear and behave.
When multiple components are placed inside a screen, developers need to control their position, alignment, spacing, and size. Jetpack Compose provides three fundamental layout composables for this purpose: Row, Column, and Box.
- Row: Arranges components horizontally, one after another.
- Column: Arranges components vertically, one below another.
- Box: Places components in the same general area, allowing alignment and overlapping.
These layouts can be combined to build more complex interfaces, such as login screens, profile cards, dashboards, product pages, navigation sections, and forms.
2. Learning Objectives
After completing this topic, learners should be able to:
- Understand the purpose of Row, Column, and Box.
- Create horizontal and vertical arrangements of composable elements.
- Control alignment and spacing using arrangement parameters.
- Use Modifier to control size, padding, background, and positioning.
- Distribute available space using weight.
- Combine nested layouts to create complete screens.
- Build overlapping UI elements using Box.
- Choose the appropriate layout for different interface requirements.
- Identify and troubleshoot common layout problems.
3. Understanding Row, Column, and Box
| Layout |
Direction or behavior |
Main purpose |
Example |
| Row |
Horizontal |
Places children next to each other. |
Profile icon beside a username. |
| Column |
Vertical |
Places children above and below one another. |
Heading, description, and button. |
| Box |
Layered or overlapping |
Places children in the same area with configurable alignment. |
Notification badge over an icon. |
For example, a profile screen might use a Column for the overall content, a Row for the profile picture and user details, and a Box to display an online-status indicator over the profile picture.
4. Understanding Row in Jetpack Compose
Row is a layout composable that arranges its children horizontally. By default, children appear next to each other in the order in which they are declared.
Row is useful when an interface needs a horizontal group of components, such as an icon and label, multiple action buttons, a profile image and user information, or a title and action icon.
4.1 Basic Row example
import androidx.compose.foundation.layout.Row
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@Composable
fun BasicRowExample() {
Row {
Text(text = "Android")
Text(text = "Development")
Text(text = "Course")
}
}
Explanation
Row creates a horizontal layout container.
- The first Text displays Android.
- The second Text appears beside the first.
- The third Text appears beside the second.
- The order of the child composables determines their normal placement order.
Without additional spacing, the components may appear too close together. Developers can use horizontal arrangement, padding, or Spacer to improve the design.
4.2 Adding horizontal spacing
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.unit.dp
@Composable
fun RowWithSpacing() {
Row(
horizontalArrangement = Arrangement.spacedBy(12.dp)
) {
Text(text = "Home")
Text(text = "Courses")
Text(text = "Contact")
}
}
Arrangement.spacedBy(12.dp) adds 12dp of space between adjacent children. It does not automatically add the same spacing before the first child or after the last child.
4.3 Aligning children vertically inside a Row
Row provides the verticalAlignment parameter to control how children align along the vertical axis.
import androidx.compose.foundation.layout.Alignment
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.height
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
@Composable
fun VerticallyAlignedRow() {
Row(
modifier = Modifier.height(80.dp),
verticalAlignment = androidx.compose.ui.Alignment.CenterVertically
) {
Text(text = "Profile")
Text(text = "Active User")
}
}
Common vertical alignment choices include:
Alignment.Top — aligns children toward the top of the Row.
Alignment.CenterVertically — centers children vertically.
Alignment.Bottom — aligns children toward the bottom.
Note: The alignment type for Row is androidx.compose.ui.Alignment. The import should be import androidx.compose.ui.Alignment if you want to use Alignment.CenterVertically directly.
4.4 Controlling horizontal arrangement
The horizontalArrangement parameter controls how children are distributed along the Row's horizontal axis when additional space is available.
| Arrangement |
Behavior |
Arrangement.Start |
Places children toward the start of the horizontal layout. |
Arrangement.End |
Places children toward the end of the horizontal layout. |
Arrangement.Center |
Groups children in the center. |
Arrangement.SpaceBetween |
Places the first and last children at opposite ends and distributes space between them. |
Arrangement.SpaceAround |
Distributes space around each child, with half-sized outer spaces relative to the inner spaces. |
Arrangement.SpaceEvenly |
Distributes equal space before, between, and after children. |
Arrangement.spacedBy(8.dp) |
Uses a specified gap between adjacent children. |
Example: SpaceBetween
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
@Composable
fun NavigationRow() {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(text = "Home")
Text(text = "Courses")
Text(text = "Profile")
}
}
Here, fillMaxWidth() requests the maximum width allowed by the parent constraints. The available width lets SpaceBetween distribute the children across the Row.
5. Understanding Column in Jetpack Compose
Column arranges its child composables vertically. Each child is positioned below the previous child, making it suitable for screens with headings, descriptions, form fields, buttons, and vertically arranged content sections.
5.1 Basic Column example
import androidx.compose.foundation.layout.Column
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@Composable
fun BasicColumnExample() {
Column {
Text(text = "Welcome to Android")
Text(text = "Learn Kotlin")
Text(text = "Build Applications")
}
}
Explanation
Column creates a vertical container.
- The first Text appears at the top.
- The second Text appears below the first.
- The third Text appears below the second.
- The children follow their declaration order unless a different layout structure is used.
5.2 Adding vertical spacing
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.unit.dp
@Composable
fun ColumnWithSpacing() {
Column(
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
Text(text = "Student Details")
Text(text = "Name: Rahul")
Text(text = "Course: Android Development")
}
}
Arrangement.spacedBy(16.dp) adds a consistent 16dp gap between adjacent children. It does not add extra spacing at the top or bottom of the Column.
5.3 Aligning children horizontally inside a Column
Column provides the horizontalAlignment parameter for aligning its children along the horizontal axis.
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.ui.Alignment
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
@Composable
fun CenteredColumn() {
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = "Welcome")
Text(text = "Android Learner")
}
}
Common horizontal alignment choices include:
Alignment.Start — aligns children toward the start of the Column.
Alignment.CenterHorizontally — centers children horizontally.
Alignment.End — aligns children toward the end.
These alignments apply within the Column's available width. For example, a Column that only occupies the width of its contents cannot center those contents across the entire screen. Use a suitable width modifier when full-width alignment is required.
5.4 Controlling vertical arrangement
The verticalArrangement parameter determines how children are distributed along the vertical axis.
| Arrangement |
Behavior |
Arrangement.Top |
Places children at the top of the available area. |
Arrangement.Bottom |
Places children toward the bottom. |
Arrangement.Center |
Groups children around the vertical center. |
Arrangement.SpaceBetween |
Distributes available space between children. |
Arrangement.SpaceAround |
Distributes space around children. |
Arrangement.SpaceEvenly |
Distributes equal space before, between, and after children. |
Arrangement.spacedBy(12.dp) |
Adds a fixed gap between adjacent children. |
6. Understanding Box in Jetpack Compose
Box is a layout composable that allows children to occupy the same general area. It is useful when elements need to overlap or align relative to a common container.
Typical use cases include:
- Displaying text over a background image.
- Placing a notification badge over an icon.
- Adding a loading indicator over existing content.
- Aligning a close button at the top-right corner of a card.
- Centering a message within an available area.
6.1 Basic Box example
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
@Composable
fun BasicBoxExample() {
Box(
modifier = Modifier.size(200.dp),
contentAlignment = Alignment.Center
) {
Text(text = "Centered Content")
}
}
Explanation
Box creates a container for its child elements.
Modifier.size(200.dp) requests a 200dp square, subject to the constraints imposed by its parent.
contentAlignment = Alignment.Center centers the children inside the Box.
- The Text appears in the center of the available Box area.
6.2 Placing multiple components inside a Box
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
@Composable
fun LayeredBoxExample() {
Box(
modifier = Modifier
.fillMaxSize()
.background(Color.LightGray)
) {
Text(
text = "Top Start",
modifier = Modifier.align(Alignment.TopStart)
)
Text(
text = "Center",
modifier = Modifier.align(Alignment.Center)
)
Text(
text = "Bottom End",
modifier = Modifier.align(Alignment.BottomEnd)
)
}
}
In this example, three Text composables share the same Box. Each child uses the Box-specific Modifier.align() function to specify its own position.
6.3 Common Box alignment positions
| Alignment |
Position |
Alignment.TopStart |
Top-left in left-to-right layouts, respecting layout direction. |
Alignment.TopCenter |
Top center. |
Alignment.TopEnd |
Top-right in left-to-right layouts, respecting layout direction. |
Alignment.CenterStart |
Vertically centered at the start. |
Alignment.Center |
Center of the Box. |
Alignment.CenterEnd |
Vertically centered at the end. |
Alignment.BottomStart |
Bottom at the start. |
Alignment.BottomCenter |
Bottom center. |
Alignment.BottomEnd |
Bottom at the end. |
The terms Start and End are layout-direction-aware. This helps interfaces work correctly in both left-to-right and right-to-left languages.
7. Understanding Main Axis and Cross Axis
Each layout has a main axis and a cross axis. Understanding these axes makes it easier to choose the correct arrangement and alignment parameters.
| Layout |
Main axis |
Cross axis |
Arrangement parameter |
Alignment parameter |
| Row |
Horizontal |
Vertical |
horizontalArrangement |
verticalAlignment |
| Column |
Vertical |
Horizontal |
verticalArrangement |
horizontalAlignment |
| Box |
No equivalent sequential main axis |
No equivalent sequential cross axis |
Not used in the same way as Row or Column |
contentAlignment and child Modifier.align() |
For Row, arrangement controls horizontal distribution and alignment controls vertical positioning. For Column, arrangement controls vertical distribution and alignment controls horizontal positioning.
8. Using Modifier with Row, Column, and Box
Modifier is used to customize the size, spacing, appearance, and interaction behavior of composables. It is essential when arranging UI elements in Compose.
Common Modifier functions
| Modifier |
Purpose |
Example |
padding() |
Adds space around or within a component according to modifier order. |
Modifier.padding(16.dp) |
fillMaxWidth() |
Requests the maximum available width allowed by constraints. |
Modifier.fillMaxWidth() |
fillMaxHeight() |
Requests the maximum available height allowed by constraints. |
Modifier.fillMaxHeight() |
fillMaxSize() |
Requests the maximum available width and height allowed by constraints. |
Modifier.fillMaxSize() |
size() |
Requests a particular size. |
Modifier.size(100.dp) |
background() |
Draws a background behind content. |
Modifier.background(Color.Gray) |
border() |
Draws a border around a component. |
Modifier.border(1.dp, Color.Black) |
clickable() |
Adds click interaction. |
Modifier.clickable { } |
Example: Combining modifiers
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
@Composable
fun ModifierExample() {
Column(
modifier = Modifier
.fillMaxWidth()
.background(Color.LightGray)
.padding(16.dp)
) {
Text(text = "Android Development")
Text(text = "Learn layouts with Compose")
}
}
Modifier order can change the result. In this example, the background is applied before the padding modifier, so the background covers the container's padded area as well. Reversing the order may cause the background to be drawn only within the padded content region.
9. Using Spacer for Additional Space
Spacer is a layout composable used to create an empty area between components. It is helpful when a specific amount of spacing is required rather than a general arrangement rule.
Example with Column
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
@Composable
fun SpacerExample() {
Column {
Text(text = "Username")
Spacer(modifier = Modifier.height(12.dp))
Text(text = "Password")
}
}
Example with Row
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
@Composable
fun HorizontalSpacerExample() {
Row {
Text(text = "Home")
Spacer(modifier = Modifier.width(20.dp))
Text(text = "Settings")
}
}
For regular gaps between every child, Arrangement.spacedBy() is often more concise. Spacer is useful when the spacing needs to be positioned explicitly or when flexible empty space is required.
10. Understanding Weight in Row and Column
The weight() modifier lets eligible children share the remaining available space inside a Row or Column. It is useful for proportional sizing and flexible layouts.
10.1 Weight in Row
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.weight
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
@Composable
fun WeightedRow() {
Row(modifier = Modifier.fillMaxWidth()) {
Text(
text = "Left",
modifier = Modifier
.weight(1f)
.background(Color.LightGray)
.padding(12.dp)
)
Text(
text = "Center",
modifier = Modifier
.weight(2f)
.background(Color.Cyan)
.padding(12.dp)
)
Text(
text = "Right",
modifier = Modifier
.weight(1f)
.background(Color.LightGray)
.padding(12.dp)
)
}
}
The three children have weights of 1, 2, and 1. After accounting for other children and applicable spacing, the remaining horizontal space is distributed proportionally. The middle child receives twice the weighted share of either outer child.
10.2 Weight in Column
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.weight
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
@Composable
fun WeightedColumn() {
Column(
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight()
) {
Text(
text = "Header",
modifier = Modifier.background(Color.LightGray)
)
Text(
text = "Main Content",
modifier = Modifier
.weight(1f)
.fillMaxWidth()
.background(Color.Cyan)
)
Text(
text = "Footer",
modifier = Modifier.background(Color.LightGray)
)
}
}
The weighted main content requests the remaining vertical space after the other children have been measured, subject to the Column's constraints.
Important: Weight is scope-specific. Use it on children within a Row or Column, and import the appropriate scope extension when required by your code structure. Weight does not have the same meaning when applied to arbitrary composables outside those layout scopes.
11. Nesting Row, Column, and Box
Real Android screens commonly combine several layout composables. A Row can contain a Column, a Column can contain Rows, and a Box can position one or more elements over another.
Example: Profile information layout
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
@Composable
fun ProfileInformation() {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start
) {
Box(
modifier = Modifier
.size(64.dp)
.background(Color.LightGray, CircleShape),
contentAlignment = Alignment.Center
) {
Text(text = "A")
}
Spacer(modifier = Modifier.width(16.dp))
Column(
verticalArrangement = Arrangement.spacedBy(4.dp)
) {
Text(text = "Amit Sharma")
Text(text = "Android Developer")
Text(text = "Mumbai, India")
}
}
}
How this layout works
- The outer Row places the avatar and profile details next to each other.
- The Box creates a circular background area for the avatar's initial.
- The Spacer creates a 16dp gap between the avatar and text.
- The Column arranges the name, role, and location vertically.
- The Row's verticalAlignment keeps the avatar and profile text group aligned along the vertical center.
This structure is reusable for user profiles, employee cards, student records, and contact lists.
12. Creating a Profile Card Using All Three Layouts
The following example demonstrates how Row, Column, and Box can work together to create a profile card. The Box is used for the avatar and online indicator, the Row places the avatar beside the user's information, and the Column arranges text vertically.
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.Card
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
@Composable
fun ProfileCard() {
Card(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
Row(
modifier = Modifier.padding(16.dp),
verticalAlignment = Alignment.CenterVertically
) {
Box(
modifier = Modifier.size(64.dp)
) {
Box(
modifier = Modifier
.size(64.dp)
.background(Color.LightGray, CircleShape),
contentAlignment = Alignment.Center
) {
Text(text = "A")
}
Box(
modifier = Modifier
.size(14.dp)
.align(Alignment.BottomEnd)
.background(Color.Green, CircleShape)
)
}
Spacer(modifier = Modifier.width(16.dp))
Column(
verticalArrangement = Arrangement.spacedBy(4.dp)
) {
Text(text = "Amit Sharma")
Text(text = "Android Developer")
Text(text = "Online")
}
}
}
}
The small green circle is aligned to the bottom-end corner of the avatar area. In a production interface, consider using a suitable semantic description for status information and ensure that color is not the only way the online state is communicated.
13. Creating a Login Screen with Row and Column
Login screens commonly use Column to arrange labels, input fields, and buttons vertically. Row can be used to arrange options horizontally, such as a checkbox beside a label or a set of social sign-in buttons.
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.Checkbox
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
@Composable
fun LoginScreen() {
var email by remember { mutableStateOf("") }
var password by remember { mutableStateOf("") }
var rememberMe by remember { mutableStateOf(false) }
Column(
modifier = Modifier
.fillMaxWidth()
.padding(24.dp),
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
Text(text = "Login")
OutlinedTextField(
value = email,
onValueChange = { email = it },
modifier = Modifier.fillMaxWidth(),
label = { Text("Email") }
)
OutlinedTextField(
value = password,
onValueChange = { password = it },
modifier = Modifier.fillMaxWidth(),
label = { Text("Password") }
)
Row(
verticalAlignment = Alignment.CenterVertically
) {
Checkbox(
checked = rememberMe,
onCheckedChange = { rememberMe = it }
)
Text(text = "Remember me")
}
Spacer(modifier = Modifier.height(4.dp))
Button(
onClick = {
// Add login validation and submission logic.
},
modifier = Modifier.fillMaxWidth()
) {
Text(text = "Login")
}
}
}
This example demonstrates layout composition and local UI state. A production login flow should add appropriate validation, secure authentication, error handling, and state management rather than implementing authentication directly inside the composable.
14. Row, Column, and Box for Responsive Layouts
These three layouts provide a foundation for responsive interfaces, but responsive behavior also depends on the constraints imposed by parent containers and the sizing modifiers applied to children.
Recommended techniques
- Use
fillMaxWidth() when a component should use the available width.
- Use
wrapContentWidth() or wrapContentSize() when content should occupy only the necessary space.
- Use weight to distribute available space between children in a Row or Column.
- Use Arrangement to control how children are distributed along the main axis.
- Use Alignment to control positioning along the cross axis.
- Use BoxWithConstraints when layout decisions need to depend on the constraints available to a composable.
- Allow text to wrap naturally and avoid unnecessary fixed dimensions.
- Test on different screen widths, orientations, and font sizes.
Example: Layout that changes based on available width
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
@Composable
fun ResponsiveInformation() {
BoxWithConstraints(
modifier = Modifier.fillMaxWidth()
) {
if (maxWidth >= 600.dp) {
Row(
horizontalArrangement = Arrangement.spacedBy(16.dp)
) {
Text(text = "Course Information")
Text(text = "Course Schedule")
}
} else {
Column(
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
Text(text = "Course Information")
Text(text = "Course Schedule")
}
}
}
}
BoxWithConstraints exposes the constraints available to its content. In this example, a wider area uses Row, while a narrower area uses Column. The 600dp threshold is only an illustrative design choice; select breakpoints based on the actual needs of your interface.
15. Handling Long Content and Scrolling
A Column arranges content vertically, but it does not automatically become scrollable. If its children exceed the available height, content may become inaccessible unless scrolling or another appropriate layout strategy is provided.
Example: Scrollable Column
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
@Composable
fun ScrollableContent() {
Column(
modifier = Modifier
.fillMaxSize()
.verticalScroll(rememberScrollState())
) {
Text(text = "Section 1")
Text(text = "Section 2")
Text(text = "Section 3")
Text(text = "Section 4")
}
}
Use a vertically scrollable Column for a relatively small amount of content that should move as a single group. For large collections of repeated items, use LazyColumn. Similarly, LazyRow is appropriate for a horizontally scrolling collection.
16. Common Mistakes and Troubleshooting
| Problem |
Possible cause |
Solution |
| Text elements appear too close together. |
No spacing or padding is applied. |
Use Arrangement.spacedBy() or Spacer. |
| Row children do not fit on a narrow screen. |
Children require more horizontal space than is available. |
Use flexible sizing, weight, scrolling, or switch to a Column when appropriate. |
| Column content is cut off vertically. |
Content exceeds the available height and the Column is not scrollable. |
Use verticalScroll or LazyColumn as appropriate. |
| Content is not centered. |
The container does not occupy the expected area or the wrong alignment parameter is used. |
Check the container size and use the correct arrangement or alignment parameter. |
| Box children overlap unexpectedly. |
Multiple children occupy the same area by design. |
Use Modifier.align(), appropriate sizes, or a Row or Column instead. |
| Weighted children have unexpected sizes. |
The parent does not have the expected available space or other children consume space. |
Inspect parent constraints, fixed-size children, and spacing. |
| Modifier changes do not produce the expected background area. |
Modifiers are applied in an unexpected order. |
Review the order of background(), padding(), size(), and other modifiers. |
| Layout looks different on a tablet. |
The design assumes a fixed screen width or height. |
Use flexible sizing and adapt the arrangement to available constraints. |
| Alignment import causes compilation errors. |
The wrong Alignment class was imported. |
Use androidx.compose.ui.Alignment for common Row, Column, and Box alignments. |
17. Best Practices for Using Row, Column, and Box
- Choose the simplest layout that matches the visual structure.
- Use Row for horizontal relationships and Column for vertical relationships.
- Use Box when children need independent alignment or layering.
- Use Arrangement and Alignment instead of manually positioning every element.
- Apply Modifier in a deliberate order.
- Use consistent dp-based spacing and appropriate sp-based text sizes.
- Use weight carefully to distribute available space.
- Avoid hard-coded dimensions that cause content to clip on smaller screens.
- Use LazyColumn and LazyRow for large or dynamically sized lists.
- Break complicated screens into smaller, reusable composable functions.
- Use semantic descriptions and accessible controls.
- Test on different screen sizes, orientations, and font settings.
18. Practical Project: Student Dashboard
Create a simple student dashboard using Row, Column, and Box. The dashboard should display a student profile, course information, and a notification badge.
Project requirements
- Create a Column as the main screen layout.
- Use a Row to display the student's avatar and personal information.
- Use a Box to place an online indicator over the avatar.
- Use another Row to display dashboard actions horizontally.
- Use Arrangement.spacedBy() to provide consistent gaps between components.
- Use Modifier.padding() to separate content from screen edges.
- Use fillMaxWidth() for cards or sections that should occupy the available width.
- Make the screen usable on both compact phones and wider displays.
Expected result
The dashboard should display the profile image or avatar beside the student's details. Below it, course information and dashboard actions should be arranged clearly. The online indicator should appear over the avatar, and all components should remain readable at different screen sizes.
19. Interview Questions and Answers
Q1. What is Row in Jetpack Compose?
Row is a layout composable that arranges its children horizontally.
Q2. What is Column in Jetpack Compose?
Column arranges its children vertically, placing each child below the previous one.
Q3. What is Box in Jetpack Compose?
Box is a layout composable that allows children to share an area and supports alignment and overlapping.
Q4. What is the difference between Row and Column?
Row arranges children along a horizontal main axis, while Column arranges children along a vertical main axis.
Q5. What is horizontalArrangement?
It controls how children are distributed horizontally inside a Row when space is available.
Q6. What is verticalArrangement?
It controls how children are distributed vertically inside a Column when space is available.
Q7. What is verticalAlignment in Row?
It controls how Row children are aligned along the vertical axis.
Q8. What is horizontalAlignment in Column?
It controls how Column children are aligned along the horizontal axis.
Q9. How do you center a child inside a Box?
Use contentAlignment = Alignment.Center to center the Box's children by default, or use Modifier.align(Alignment.Center) on a specific child.
Q10. What is Arrangement.spacedBy() used for?
It creates a specified gap between adjacent children in Row or Column.
Q11. What is the purpose of Spacer?
Spacer creates an empty area with a specified or flexible size between components.
Q12. What does Modifier.weight() do?
It allows a child in a Row or Column to receive a proportional share of the remaining available space.
Q13. Can Row, Column, and Box be nested?
Yes. They can be combined to create complex layouts. For example, a Row can contain a Column, and a Box can overlay a badge on an avatar.
Q14. How can you make a Column scrollable?
Use verticalScroll(rememberScrollState()) for a single scrolling content area. Use LazyColumn for large lists of items.
Q15. What is the difference between Box alignment and Row or Column alignment?
Box uses contentAlignment and child-level Modifier.align() to position elements within a shared area. Row and Column use arrangement and alignment parameters suited to their sequential horizontal or vertical layouts.
20. Quick Revision Notes
- Row: Arranges components horizontally.
- Column: Arranges components vertically.
- Box: Supports layered content and independent child alignment.
- horizontalArrangement: Controls horizontal distribution in Row.
- verticalArrangement: Controls vertical distribution in Column.
- verticalAlignment: Controls vertical alignment in Row.
- horizontalAlignment: Controls horizontal alignment in Column.
- contentAlignment: Defines the default alignment of Box children.
- Modifier.align(): Positions an individual child within a compatible layout scope.
- Arrangement.spacedBy(): Adds a consistent gap between adjacent children.
- Spacer: Creates an empty area between components.
- weight(): Distributes available space proportionally among eligible Row or Column children.
- BoxWithConstraints: Exposes the constraints available to its content for responsive layout decisions.
- LazyColumn: Efficiently displays large vertically scrolling collections.
21. Conclusion
Row, Column, and Box are the fundamental layout building blocks in Jetpack Compose. Row organizes components horizontally, Column organizes them vertically, and Box supports overlapping elements and flexible alignment.
By combining these composables with Modifier, Arrangement, Alignment, Spacer, and weight, developers can build clear, maintainable, and responsive Android interfaces. Practice with profile cards, login forms, dashboards, and responsive screens to understand how these layouts work together in real applications.
Useful Learning Links: